package logger

import (
	"fmt"
	"io"
	"os"
	"path"
	"sorm/utils"
	"time"
)

type FileLogger struct {
	Level    Level
	FileName string
	FilePath string
	File     *os.File
	ErrFile  *os.File
	Writer   io.Writer
}

func NewFileLogger(level string, FileName string, FilePath string) *FileLogger {
	f := &FileLogger{
		Level:    ParseLogLevel(level),
		FileName: FileName,
		FilePath: FilePath,
	}
	f.initFileLogger()
	return f
}

func (f *FileLogger) initFileLogger() {
	LogName := path.Join(f.FilePath, f.FileName)
	file, err := os.OpenFile(LogName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0664)
	if err != nil {
		panic(fmt.Errorf("Error open log file %s:%v", LogName, err))
	}
	f.File = file

	errLogFileName := fmt.Sprintf("%s.err", LogName)
	errFile, err := os.OpenFile(errLogFileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0664)
	if err != nil {
		panic(fmt.Errorf("Error open err log file %s:%v", LogName, err))
	}
	f.ErrFile = errFile
	f.Writer = io.MultiWriter(os.Stdout, f.File, f.ErrFile)
}

func (f *FileLogger) log(level Level, format string, args ...interface{}) {
	if f.Level > level {
		return
	}
	message := fmt.Sprintf(format, args...)
	nowStr := time.Now().Format("2006-01-02 15:04:05")
	fileName, line, funcName := utils.GetCallerInfo(2)
	logMessage := fmt.Sprintf("[%s] [%s] [%d] [%s] %s", nowStr, fileName, line, funcName, getLevel(level), message)
	fmt.Fprintln(f.Writer, logMessage)

	if f.Level > Error {
		fmt.Fprintln(f.ErrFile, logMessage)
	}
}

func (f *FileLogger) Debug(format string, args ...interface{}) {
	f.log(Debug, format, args...)
}

func (f *FileLogger) Info(format string, args ...interface{}) {
	f.log(Info, format, args...)
}

func (f *FileLogger) Warning(format string, args ...interface{}) {
	f.log(Warning, format, args...)
}
func (f *FileLogger) Error(format string, args ...interface{}) {
	f.log(Error, format, args...)
}

func (f *FileLogger) Fatal(format string, args ...interface{}) {
	f.log(Fatal, format, args...)
}
